%     FASTENER DOCTOR - программа для лечения и конвертации крепежа
%     Copyright (C) 2018-2019  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

function [e1, e2, e3, origin] = Coord_Vectors (index, COORD)

global ErrCode;

if (COORD{index}.Reference_Coord_ID == 0) % Референсная система координат - это глобальная система координат
    
    switch upper(COORD{index}.card) % Ветвление по тому, каким образом задана текушая система координат
        
        case 'CORD2R'
            
            A = COORD{index}.A;
            B = COORD{index}.B;
            C = COORD{index}.C;
            
            e3 = B - A;
            e2 = cross(B - A, C - A);
            e1 = cross(e2, e3);

            e1 = e1 / norm(e1);
            e2 = e2 / norm(e2);
            e3 = e3 / norm(e3);
            
            origin = A;

        case 'CORD2C'
            
            A = COORD{index}.A;
            B = COORD{index}.B;
            C = COORD{index}.C;
            
            e3 = B - A;
            e2 = cross(B - A, C - A);
            e1 = cross(e2, e3);

            e1 = e1 / norm(e1);
            e2 = e2 / norm(e2);
            e3 = e3 / norm(e3);
            
            origin = A;
            
        otherwise
            
            e1 = [];
            e2 = [];
            e3 = [];
            origin = [];
            ErrCode = -2;
            return;
        
    end

else
    
    % Нахождение базисных векторов референсной СК в глобальной с помощью рекурсивного вызова
    
    Find_flag = 0;
    
    for i=1:size(COORD,1)
        if (COORD{i}.ID == COORD{index}.Reference_Coord_ID)
            Find_flag = 1;
            break;
        end
    end
    
    if (Find_flag == 0)
        
        e1 = [];
        e2 = [];
        e3 = [];
        origin = [];
        ErrCode = -1;
        return;
        
    else
        
        [e1_ref, e2_ref, e3_ref, origin_ref] = Coord_Vectors (i, COORD);
        
        if (ErrCode < 0)
            e1 = [];
            e2 = [];
            e3 = [];
            origin = [];
            return;
        end
        
    end
    
    % Нахождение базисных векторов текущей СК в референсной
    
    switch upper(COORD{i}.card) % Ветвление по тому, какого типа референсная система координат
        
        case 'CORD2R' % Референсная СК прямоугольная
            
            switch upper(COORD{index}.card) % Ветвление по тому, каким образом задана текушая система координат
                
                case 'CORD2R' % Задание текущей СК согласно карточке CORD2R
                    
                    A = COORD{index}.A; % Референсная СК прямоугольная
                    B = COORD{index}.B; % Референсная СК прямоугольная
                    C = COORD{index}.C; % Референсная СК прямоугольная
                    
                    e3_local = B - A; % Задание текущей СК согласно карточке CORD2R
                    e2_local = cross(B - A, C - A); % Задание текущей СК согласно карточке CORD2R
                    e1_local = cross(e2_local, e3_local); % Задание текущей СК согласно карточке CORD2R
                    
                    origin_local = A; % Задание текущей СК согласно карточке CORD2R
                    
                case 'CORD2C' % Задание текущей СК согласно карточке CORD2C
                    
                    A = COORD{index}.A; % Референсная СК прямоугольная
                    B = COORD{index}.B; % Референсная СК прямоугольная
                    C = COORD{index}.C; % Референсная СК прямоугольная
                    
                    e3_local = B - A; % Задание текущей СК согласно карточке CORD2C
                    e2_local = cross(B - A, C - A); % Задание текущей СК согласно карточке CORD2C
                    e1_local = cross(e2_local, e3_local); % Задание текущей СК согласно карточке CORD2C
                    
                    origin_local = A; % Задание текущей СК согласно карточке CORD2R
                    
                otherwise
                    
                    e1 = [];
                    e2 = [];
                    e3 = [];
                    origin = [];
                    ErrCode = -2;
                    return;
                
            end

        case 'CORD2C' % Референсная СК цилиндрическая
            
            switch upper(COORD{index}.card) % Ветвление по тому, каким образом задана текушая система координат
                
                case 'CORD2R' % Задание текущей СК согласно карточке CORD2R
                    
                    A = [COORD{index}.A(1)*cosd(COORD{index}.A(2)); COORD{index}.A(1)*sind(COORD{index}.A(2)); COORD{index}.A(3)]; % Референсная СК цилиндрическая
                    B = [COORD{index}.B(1)*cosd(COORD{index}.B(2)); COORD{index}.B(1)*sind(COORD{index}.B(2)); COORD{index}.B(3)]; % Референсная СК цилиндрическая
                    C = [COORD{index}.C(1)*cosd(COORD{index}.C(2)); COORD{index}.C(1)*sind(COORD{index}.C(2)); COORD{index}.C(3)]; % Референсная СК цилиндрическая
                    
                    e3_local = B - A; % Задание текущей СК согласно карточке CORD2R
                    e2_local = cross(B - A, C - A); % Задание текущей СК согласно карточке CORD2R
                    e1_local = cross(e2_local, e3_local); % Задание текущей СК согласно карточке CORD2R
                    
                    origin_local = A; % Задание текущей СК согласно карточке CORD2R
                    
                case 'CORD2C' % Задание текущей СК согласно карточке CORD2C
                    
                    A = [COORD{index}.A(1)*cosd(COORD{index}.A(2)); COORD{index}.A(1)*sind(COORD{index}.A(2)); COORD{index}.A(3)]; % Референсная СК цилиндрическая
                    B = [COORD{index}.B(1)*cosd(COORD{index}.B(2)); COORD{index}.B(1)*sind(COORD{index}.B(2)); COORD{index}.B(3)]; % Референсная СК цилиндрическая
                    C = [COORD{index}.C(1)*cosd(COORD{index}.C(2)); COORD{index}.C(1)*sind(COORD{index}.C(2)); COORD{index}.C(3)]; % Референсная СК цилиндрическая
                    
                    e3_local = B - A; % Задание текущей СК согласно карточке CORD2C
                    e2_local = cross(B - A, C - A); % Задание текущей СК согласно карточке CORD2C
                    e1_local = cross(e2_local, e3_local); % Задание текущей СК согласно карточке CORD2C
                    
                    origin_local = A; % Задание текущей СК согласно карточке CORD2R
                    
                otherwise
                    
                    e1 = [];
                    e2 = [];
                    e3 = [];
                    origin = [];
                    ErrCode = -2;
                    return;
                
            end
            
        otherwise
            
            e1 = [];
            e2 = [];
            e3 = [];
            origin = [];
            ErrCode = -2;
            return;

    end
    
    % Перевод базисных векторов текущей СК из референсной СК в глобальную и нормировка

    e1 = [e1_ref, e2_ref, e3_ref]*e1_local;
    e2 = [e1_ref, e2_ref, e3_ref]*e2_local;
    e3 = [e1_ref, e2_ref, e3_ref]*e3_local;
    
    e1 = e1 / norm(e1);
    e2 = e2 / norm(e2);
    e3 = e3 / norm(e3);
    
    % Вычисление начала текущей СК в глобальной
    
    origin = origin_ref + [e1_ref, e2_ref, e3_ref]*origin_local;
    
end
